// PersistentVisitor.cpp: implementation of the PersistentVisitor class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "PersistentVisitor.h"
#include "Volume.h"
#include "ProjectManager.h"
#include "DBConnectionManager.h"
#include <fstream.h>
#include "PropertyStack.h"
#include "PartTypeVariable.h"

using namespace PropertySystem;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

using namespace DAWrapper;
namespace PersistentObjectOperation
{
	UE_IMPLEMENT_MULTI_INHERIT_DYNAMIC(PersistentVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(PersistentVisitor, PersistentObjectVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(PersistentVisitor, VolumeVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(PersistentVisitor, PartVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(PersistentVisitor, JointVisitor)
		UE_IMPLEMENT_PARENT_DYNAMIC(PersistentVisitor, SHVisitor)
	UE_IMPLEMENT_MULTI_INHERIT_END()

	PersistentVisitor::PersistentVisitor()
	{
		m_bHasModelElement = FALSE;		
	}
	
	PersistentVisitor::~PersistentVisitor()
	{
		
	}

	const _ConnectionPtr& PersistentVisitor::ProjectConnection(Project* pCurPrj)
	{
		if(pCurPrj == NULL)
			pCurPrj = GetProjectManager().CurProject();

		ASSERT(pCurPrj);

		CString strSource = pCurPrj->ProjectPath() + pCurPrj->ProjectSource();
		ASSERT(!strSource.IsEmpty());

		return *DBConnectionManager::Instance()->GetConnectionPtrByUri(strSource);
	}

	BOOL PersistentVisitor::PersistentExecute(const CString& strSql, Project* pCurPrj)
	{
		try
		{
			const _ConnectionPtr& pCon = this->ProjectConnection(pCurPrj);
			pCon->Execute(_bstr_t(strSql), NULL, adCmdText);
		}
		catch(_com_error e)
		{
			ASSERT(FALSE);
			ErrorAlert(e);
#if defined(_ARXDEBUG) || defined(_DEBUG)
			AfxMessageBox(strSql);
			fstream file(_T("c:\\sql.txt"), ios::out|ios::trunc);
			file<<strSql;
			file.close();
#endif
			return FALSE;
		}
		return TRUE;
	}
	
	void PersistentVisitor::GetAttachOfModel(ModelObject* pObj)
	{
		BOOL bResult = TRUE;
		ASSERT(pObj);
		PropertyStack* pStack = pObj->GetPropertyStack();
		ASSERT(pStack);

		PropertyStack::Iterator* pIterator = pStack->NewSavePropertyIterator();
		if(pIterator == NULL)
		{
			ASSERT(pIterator);
			::ReportMemoryError();
		}

		for(pIterator->Begin(); !pIterator->End(); pIterator->Next())
		{
			Variable* pVar = pIterator->Get();
			ASSERT(pVar);
			ASSERT(!pVar->GetSymbol().IsEmpty());

			if(pVar->IsKindOf(UE_RUNTIME_CLASS(PropertySystem::PartTypeVariable)))
			{
				Part* pSubPart = (Part*)(*pVar);
				bResult = Visit(pSubPart);
			}
			ASSERT(bResult);

		}
		delete pIterator;
		
	}

	
	BOOL PersistentVisitor::Visit(Volume*& pVolume)
	{
		ASSERT(pVolume);
		ASSERT(pVolume->IsCreateState());

		m_theVolumes.Add(pVolume);
		return TRUE;
	}
	
	BOOL PersistentVisitor::Visit(Part*& pPart)
	{
		ASSERT(pPart);
		ASSERT(pPart->IsCreateState());
		ASSERT(pPart->SupportHangerOwner());

		m_theParts.Add(pPart);
		GetAttachOfModel(pPart);
		m_bHasModelElement = TRUE;
		return TRUE;
	}
	
	BOOL PersistentVisitor::Visit(SupportHanger*& pSH)
	{
		ASSERT(pSH);
		ASSERT(pSH->IsCreateState());
		ASSERT(pSH->SupportHangerEntry());

		m_theSHs.Add(pSH);
		GetAttachOfModel(pSH);
		m_bHasModelElement = TRUE;
		return TRUE;
	}
	
	BOOL PersistentVisitor::Visit(Joint*& pJoint)
	{
		ASSERT(pJoint);
		ASSERT(pJoint->IsCreateState());
		ASSERT(pJoint->SupportHangerOwner());

		m_theJoints.Add(pJoint);
		GetAttachOfModel(pJoint);
		m_bHasModelElement = TRUE;
		return TRUE;
	}
}